package org.tiny.autounit.core.data.transport.server.codec;

import com.alibaba.fastjson.JSON;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

import java.util.ArrayList;
import java.util.List;

/**
 * @author shichaoyang
 * @Description: protostuff进行二进制序列化，反序列化
 * @date 2018-11-29 21:55
 */
public class SerializeUtil {

    private static class SerializeData{
        private Object target;
    }

    @SuppressWarnings("unchecked")
    public static byte[] serialize(Object object) {
        SerializeData serializeData = new SerializeData();
        serializeData.target = object;
        Class<SerializeData> serializeDataClass = (Class<SerializeData>) serializeData.getClass();
        LinkedBuffer linkedBuffer = LinkedBuffer.allocate(1024 * 4);
        try {
            Schema<SerializeData> schema = RuntimeSchema.getSchema(serializeDataClass);
            return ProtobufIOUtil.toByteArray(serializeData, schema, linkedBuffer);
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            linkedBuffer.clear();
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T deserialize(byte[] data, Class<T> clazz) {
        try {
            Schema<SerializeData> schema = RuntimeSchema.getSchema(SerializeData.class);
            SerializeData serializeData = schema.newMessage();
            ProtobufIOUtil.mergeFrom(data, serializeData, schema);
            return (T) serializeData.target;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    public static void main(String...args) throws Exception {

        User user = new User();
        user.setUserId(123456);
        user.setAddress("I am a good boy");
        user.setNote("this is test");

        List<String> list = new ArrayList<>();
        list.add("record1");
        list.add("record2");
        list.add("record3");
        user.setRecords(list);

        Teacher teacher1 = new Teacher();
        teacher1.setName("语文老师");
        Teacher teacher2 = new Teacher();
        teacher2.setName("数学老师");
        List<Teacher> teachers = new ArrayList<>();
        teachers.add(teacher1);
        teachers.add(teacher2);
        user.setTeachers(teachers);

        byte[] b = serialize(user);

        User rst = deserialize(b, User.class);

        System.out.println(JSON.toJSONString(rst));
    }
}

class User {
    private Integer userId;
    private String address;
    private String note;
    private List<String> records;
    private List<Teacher> teachers;

    public Integer getUserId() {
        return userId;
    }
    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }

    public List<String> getRecords() {
        return records;
    }

    public void setRecords(List<String> records) {
        this.records = records;
    }

    public List<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(List<Teacher> teachers) {
        this.teachers = teachers;
    }
}

class Teacher{
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
